#include <stdlib.h>
#include <stdio.h>

#include "common.h"
#include "cic.h"

static bool rom_load(const char* filename)
{
	FILE* rom_dump = fopen(filename, "rb");
	if (!rom_dump)
	{
		printf("failed to load %s\n", filename);
		return false;
	}

	fseek(rom_dump, 0, SEEK_END);
	size_t rom_size = ftell(rom_dump);
	fseek(rom_dump, 0, SEEK_SET);

	cpu.model = (rom_size == 768) ? MODE_3195A : MODE_6113;

	cpu.rom = new u8[rom_size];
	fread(cpu.rom, rom_size, 1, rom_dump);

	fclose(rom_dump);
	return true;
}

static void rom_unload()
{
	delete[] cpu.rom;
}

static u8 rom_fetch_op()
{
	u8 op = cpu.rom[0x80*(cpu.pc.i.segment >> 1) + cpu.pc.i.offset];
	// compute next pc
	u8 bit = ((cpu.pc.i.offset >> 1) ^ cpu.pc.i.offset) & 1;
	cpu.pc.i.offset = (cpu.pc.i.offset >> 1) ^ (bit << 6) ^ 0x40;
	return op;
}

inline u4 ram_read_nybble()
{
	return cpu.ram[cpu.b.value];
}

inline void ram_write_nybble(u4 val)
{
	cpu.ram[cpu.b.value] = val.value;
}


static bool stream_load(const char* filename, const u8* dest)
{
	FILE* stream_dump = fopen(filename, "rb");
	if (!stream_dump)
	{
		printf("failed to load %s\n", filename);
		return false;
	}

	fseek(stream_dump, 0, SEEK_END);
	size_t stream_size = ftell(stream_dump);
	fseek(stream_dump, 0, SEEK_SET);

	fread((void*)dest, stream_size, 1, stream_dump);

	fclose(stream_dump);
	return true;
}
